<html>
<head><meta charset="utf-8"><title>High-level architectue of rust-analyzer · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html">High-level architectue of rust-analyzer</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="178085505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178085505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178085505">(Oct 14 2019 at 09:00)</a>:</h4>
<p>I think it's time we split <code>ra_hir</code> into some pieces. It takes ages to compiler, and is a single crate which does <em>everything</em> (with a notable exception of macro_by_example and parsing, which do live in separate crates). I wonder how we actually go about doing that :)</p>
<p>What I like about current situation:</p>
<ul>
<li>separation between <code>ra_hir</code> and <code>ra_ide_api</code> (we should rename it to use <code>ra_ide</code>): ide layer does a ton of stuff on top of hir, and doesn't care at all about incricate details of type inference.</li>
<li>OO-style API for code model feels neat (the way ExprIds need to be threaded via <code>SourceAnalyzer</code> spoils a picture a bit, but presumably this can be fixed)</li>
</ul>
<p>What I dislike about this solution is that OO interface forces everything to hang of of defs, which makes things harder to split. (like, if we split nameres and type inference, where would <code>struct Function</code> live? What about <code>Function::signature</code>?)</p>
<p>What is good for factoring is the db API: <code>db.body(def)</code>, <code>db.ty(def)</code>, where it seems like we can have a crate which only defines IDs, and than a bunch of analysis crates, which add various <em>methods</em> to the ids via different DBs.</p>
<p>I wonder if we should split <code>ra_hir</code></p>
<p>into </p>
<div class="codehilite"><pre><span></span>ra_hir -- OO facade
  hir_ids (defines defs and `Body`)
  hir_lower ( provides `DefDatabase` over hir_ids)
  hir_ty (provides `TyDatabase` over hir_ids by using DefDatabase)
</pre></div>


<p>Note that means that, outside of hir, we will be doing <code>a_struct.fields(hir_db)</code>, while inside <code>hir_ty</code> we will be doing <code>def_db.struct_fields(a_struct)</code></p>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> <span class="user-mention" data-user-id="129457">@Florian Diebold</span> what do you think about this?  Should we perhaps create some markdown docs to scratch ideas?</p>



<a name="178092564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178092564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178092564">(Oct 14 2019 at 10:51)</a>:</h4>
<p>that probably makes sense... I don't know how much splitting the crate will help with compile times, but we should certainly split out the type inference</p>



<a name="178097855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178097855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178097855">(Oct 14 2019 at 12:21)</a>:</h4>
<p>So, what would be the next step here? Clearly, we can't just move types into a <code>ra_hir_ty</code> crate, because we still need <code>ra_hir</code> which has types. So perhaps we should not split out type inference, but everything else instead? Arghs, this seems tricky. I guess, someone (probably me) should just look into this?</p>



<a name="178098316"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178098316" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jeremy Kolb <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178098316">(Oct 14 2019 at 12:29)</a>:</h4>
<p>I don't see a problem other than the difference in API between crates could be confusing so heavy docs and consistent visibility are a must.</p>



<a name="178099238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178099238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jason Williams <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178099238">(Oct 14 2019 at 12:43)</a>:</h4>
<p>Howdy</p>



<a name="178192008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178192008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178192008">(Oct 15 2019 at 13:21)</a>:</h4>
<p>tried splitting the thing in two here: <a href="https://github.com/rust-analyzer/rust-analyzer/pull/2017" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/pull/2017">https://github.com/rust-analyzer/rust-analyzer/pull/2017</a></p>



<a name="178192052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178192052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178192052">(Oct 15 2019 at 13:21)</a>:</h4>
<p>It's not too bad in that it's actually possible to just mechanically split the code with little changes. But it's bad in a sense that I don't see a clear boundary we want to split at.</p>



<a name="178198030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178198030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178198030">(Oct 15 2019 at 14:21)</a>:</h4>
<p>hm... maybe we should actually have at least an idea how to handle expression-level items before we split this up?</p>



<a name="178217932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178217932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178217932">(Oct 15 2019 at 17:59)</a>:</h4>
<p>I want to move <code>ExprId / ExprKind</code> and lowering code to this extracted piece as well, precisely because I think expr-level items will interract with local scopes</p>



<a name="178220141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178220141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178220141">(Oct 15 2019 at 18:20)</a>:</h4>
<p>OTOH, it might actually be enough to get the tree of 'anonymous modules' from the body and have the <code>Expr::Block</code>s link back to them -- the name resolution doesn't actually care about expressions, I think</p>



<a name="178220162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178220162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178220162">(Oct 15 2019 at 18:21)</a>:</h4>
<p>the question would of course be how to get that without knowing about expressions ;)</p>



<a name="178221497"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178221497" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178221497">(Oct 15 2019 at 18:36)</a>:</h4>
<blockquote>
<p>the name resolution doesn't actually care about expressions, I think</p>
</blockquote>
<p>Error reporting sometimes cares: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2cd9c8e9bd6725e712f451cf1c11f33c" target="_blank" title="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2cd9c8e9bd6725e712f451cf1c11f33c">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2cd9c8e9bd6725e712f451cf1c11f33c</a></p>
<p>But yeah, in general, there are two dimensions across which we might cut: bodies/modules (roughtly, the current split between DefDb and HirDb) and before types / after types.</p>



<a name="178221534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178221534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178221534">(Oct 15 2019 at 18:36)</a>:</h4>
<p>I am not sure which split is better, but I lean towards the first one. Specifically because it'll let us keep Resolver separated from types</p>



<a name="178221601"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178221601" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178221601">(Oct 15 2019 at 18:37)</a>:</h4>
<p>And perhaps the first-order bit is to split "something", just to get more experience with salsa database being split non-trivially across several crates</p>



<a name="178221666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178221666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178221666">(Oct 15 2019 at 18:38)</a>:</h4>
<p>In particular, I feel that our current OO thinking of code model just falls apart if we start splitting code :)</p>



<a name="178225455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178225455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178225455">(Oct 15 2019 at 19:19)</a>:</h4>
<p>Let me also write down some possible API flavors for spliting compiler databases over several crates. </p>
<p><strong>OO-ish</strong></p>
<p>This is how the current hir works. Every entity, such as a <code>Struct</code>, has a bunch of methods which take a <code>&amp;db</code> arg and return some piece of data. The nice thing with this approach is that it is code-completion friendly and is easy to read. The main drawback is that inherent methods can be defined only in a single crate, so, <code>Struct::ty</code> would have to be implemented via a trait, which might bring more complexity, especially for one-off private utility methods. The second drawback is that this approach is less efficient: projecting a field out of a <code>StructData</code> requires some sort of cloning, and getting two fields out of <code>StructData</code> requires to queries for <code>StructData</code>, because they are hidden behind accessors</p>
<p><strong>Raw Data</strong></p>
<p>This is the simplest thing which can work in salsa, and how the code in the branch above works. Basically, every entity is just an ID without methods. To do anything, you need to <code>db.struct_data(struct_id)</code>. <code>StrcutData</code> contains local IDs, so you need to massage those to get absolute ids. The first benefit of this approach is that it's the simplest one that could work. The second benefit is that it works really well with spliting code across crate: the set of things you can do with <code>StructId</code> is different depending on whether you have a <code>DefDatabase</code> or <code>HirDatabase</code>.</p>
<p>The two drawbacks are:</p>
<ul>
<li>it's less completion friendly and less readable. </li>
<li>it's super unclear how to add utility functions. That is, if <code>db.crate_graph() -&gt; CrateGraph</code> is a query, then <code>crate_dependencies()</code>, which projecs some data from CrateGraph, needs to live as a free function <em>somewhere</em>, which is even less discoverable</li>
<li>it somewhat exposes raw data representation, and might make harder to change this data repr (not sure if this is really true though, it might actually make refactoring simpler because there are fewer wrappers everywhere)</li>
</ul>
<p><strong>Bound Entities</strong></p>
<p>That's somewhat of a merger beween the two approaches, where the api is <code>db.get(struct_id).fields()</code>, where <code>get</code> returns a <code>struct StructApi { db: &amp;DB, id: StructId}</code>. It seems like a brute force way to combine the benefits of the previous too approahces, but feels pretty complex to me. I don't have a good feeling about how it'll work in pratice.</p>
<p><strong>My prefered approach</strong></p>
<p>I think I currently lean towards rewriting everything we have in <code>hir</code> in terms of <strong>raw data</strong> approach, moving it into separate crates, and then implementing <strong>oo</strong> approach in the umbrella <code>hir</code> crate, solely as an API for IDE.</p>



<a name="178376609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/178376609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jason Williams <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#178376609">(Oct 17 2019 at 12:40)</a>:</h4>
<p>(deleted)</p>



<a name="179068502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068502">(Oct 25 2019 at 17:00)</a>:</h4>
<p><span class="user-mention" data-user-id="133169">@matklad</span> -- is this what you wanted to discuss?</p>



<a name="179068507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068507">(Oct 25 2019 at 17:00)</a>:</h4>
<p>should I catch up on this topic first?</p>



<a name="179068663"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068663" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068663">(Oct 25 2019 at 17:02)</a>:</h4>
<p>Yeah, this is related</p>



<a name="179068685"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068685" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068685">(Oct 25 2019 at 17:02)</a>:</h4>
<p>I just skimmed the topic</p>



<a name="179068695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068695">(Oct 25 2019 at 17:02)</a>:</h4>
<p>but if you would rather chat in some other place (salsa zulip?) that's fine</p>



<a name="179068708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068708">(Oct 25 2019 at 17:02)</a>:</h4>
<p>I've also made a hackmd doc in the salsa zulip,</p>



<a name="179068725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068725">(Oct 25 2019 at 17:03)</a>:</h4>
<p>yeah, I feel like salsa's zuplip might be a better fit here</p>



<a name="179068733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068733">(Oct 25 2019 at 17:03)</a>:</h4>
<p>ok :)</p>



<a name="179068746"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/High-level%20architectue%20of%20rust-analyzer/near/179068746" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/High-level.20architectue.20of.20rust-analyzer.html#179068746">(Oct 25 2019 at 17:03)</a>:</h4>
<p><a href="https://salsa.zulipchat.com/#narrow/stream/145099-general/topic/Physical.20Architecture.20of.20Large.20Scale.20Salsa-based.20Compilers" target="_blank" title="https://salsa.zulipchat.com/#narrow/stream/145099-general/topic/Physical.20Architecture.20of.20Large.20Scale.20Salsa-based.20Compilers">https://salsa.zulipchat.com/#narrow/stream/145099-general/topic/Physical.20Architecture.20of.20Large.20Scale.20Salsa-based.20Compilers</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>